namespace FileExplorerServiceHost
{
    using System;
    using System.ComponentModel;
    using System.ServiceModel;
    using System.Windows;

    using FileExplorerService;

    public class MainViewModel : INotifyPropertyChanged, IDisposable
    {
        private ServiceHost _serviceHost;

        private FileExchangeService _fileService;

        private bool _isOpen;

        private string status;

        public String CurrentDownloadDirectory{get
        {
            return _fileService.CurrentDownloadDirectory;
        }
        set
        {
            _fileService.CurrentDownloadDirectory = value;
        }}

        public String CurrentUploadDirectory
        {
            get
            {
                return _fileService.CurrentUploadDirectory;
            }
            set
            {
                _fileService.CurrentUploadDirectory = value;
            }
        }

        public MainViewModel()
        {
            _fileService = new FileExchangeService();
            _serviceHost = new ServiceHost(_fileService);
            status = "OK";
            _fileService.StartEvent += new EventHandler<StartedEventArgs>(_fileService_StartEvent);
            _fileService.EndEvent += new EventHandler<EventArgs>(_fileService_EndEvent);
            _fileService.ErrorEvent += new Action<Exception>(_fileService_ErrorEvent);
            _serviceHost.Faulted += new EventHandler(_serviceHost_Faulted);
        }

        void _fileService_ErrorEvent(Exception obj)
        {
            MessageBox.Show("Exception: " + obj);
        }

        void _serviceHost_Faulted(object sender, EventArgs e)
        {
            var dispatcher = App.Current.Dispatcher;
            if (dispatcher != null)
            {
                dispatcher.BeginInvoke(
                    new Action(() =>
                    {
                        Status = "Error!" ;
                    }));
            }
        }

        void _fileService_EndEvent(object sender, EventArgs e)
        {
            var dispatcher = App.Current.Dispatcher;
            if (dispatcher != null)
            {
                dispatcher.BeginInvoke(
                    new Action(() =>
                    {
                        Status = "OK";
                    }));
            }
        }

        void _fileService_StartEvent(object sender, StartedEventArgs e)
        {
            var dispatcher = App.Current.Dispatcher;
            if (dispatcher != null)
            {
                dispatcher.BeginInvoke(
                    new Action(() =>
                        {
                            if (e.Read)
                            {
                                Status = "Start Sending: " + e.Path;
                            }
                            else
                            {
                                Status = "Start Receiving: " + e.Path;
                            }
                        }));
            }
        }

        public void Start()
        {
            if (_isOpen)
            {
                return;
            }
            _serviceHost.Open();
            _isOpen = true;
        }

        public string Status
        {
            get
            {
                return status;
            }

            set
            {
                status = value;
                this.NotifyPropertyChanged("Status");
            }
        }

        public void Dispose()
        {
            this.Dispose(true);
        }

        private void Dispose(bool disposing)
        {
            if (disposing)
            {
                Stop();
            }
        }

        public void Stop()
        {
            if (_isOpen)
            {
                _serviceHost.Close();
                _isOpen = false;
            }
        }

        public event PropertyChangedEventHandler PropertyChanged;

        public void NotifyPropertyChanged(string property)
        {
            PropertyChangedEventHandler handler = this.PropertyChanged;
            if (handler != null)
            {
                handler(this, new PropertyChangedEventArgs(property));
            }
        }
    }
}